(function ($) {
    if ($.fn.customSwitch) {
        return;
    }

    function change_state (label, shadow) {
        if (shadow.is (':checked')) {
            label.removeClass ('off').addClass ('on');
        } else {
            label.removeClass ('on').addClass ('off');
        }
    }

    $.fn.customSwitch = function () {
        var opts, command, disabled;
        if (typeof arguments[0] === 'string') {
            command = arguments [0];
        } else {
            opts = arguments[0];
        }

        return this.each (function () {
            var self = $(this).hide (), created = self.data ('created'), view, settings, id;
            if (!created) {
                id = Math.random ().toString ().substring (2);
                view = $('<i class="cs-switch"/>').attr ('data-csi', id).insertAfter(self);
                self.data ('created', true).attr ('data-random-id', id);
                change_state (view, self);
                view.on ('click', function () {
                    if ($(this).hasClass ('disabled')) {
                        return;
                    }

                    settings = self.data ('settings');
                    if (settings && ('beforestatechange' in settings) && (typeof settings.beforestatechange === 'function')) {
                        if (settings.beforestatechange.apply (self[0], {settings:settings}) === false) {
                            return;
                        }
                        self.prop ('checked', view.hasClass ('off'));
                        change_state (view, self);
                        self.trigger ('change');
                    } else {
                        self.prop ('checked', view.hasClass ('off'));
                        change_state (view, self);
                        self.trigger ('change');
                    }
                });
            } else {
                id = self.attr ('data-random-id');
                view = $('.cs-switch[data-csi=' + id + ']');
            }

            if (typeof opts === 'object') {
                self.data ('settings', opts);
                if ('disabled' in opts) {
                    if (opts['disabled'] === true || opts['disabled'] === 'true' || opts['disabled'] === 'disabled') {
                        disabled = true;
                    }
                }
            }

            if (!disabled) {
                if (self.hasClass ('disabled')) {
                    disabled = true;
                } else if (self.is (':disabled')) {
                    disabled = true;
                }
            }
            if (disabled) {
                view.addClass ('disabled');
            }

            if (command) switch (command) {
                case 'on':
                    self.prop ('checked', true);
                    change_state (view, self);
                    self.trigger ('change');
                    break;

                case 'off':
                    self.prop ('checked', false);
                    change_state (view, self);
                    self.trigger ('change');
                    break;

                case 'toggle':
                    self.prop ('checked', !self.is (':checked'));
                    change_state (view, self);
                    self.trigger ('change');
                    break;

                case 'update':
                    change_state (view, self);
                    break;

                case 'destroy':
                    self.show ().removeData ('settings').removeData ('created').removeAttr ('data-random-id');
                    view.remove ();
                    break;

                case 'disable':
                    view.addClass ('disabled');
                    self.prop ('disabled', true);
                    break;

                case 'enable':
                    view.removeClass ('disabled');
                    self.prop ('disabled', false);
                    break;
            }
        });
    };

    $(function () {
        $('.custom-switch').customSwitch ();
    });
}) (jQuery);